<?php
declare (strict_types=1);

namespace app\service\logic\common\chat;

use app\facade\StringFacade;
use app\model\communal\ImFriendsExpertModel;
use app\model\communal\ImMessageModel;
use app\service\logic\BaseService;
use Carbon\Carbon;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\db\Query;
use think\facade\Db;

final class FriendsExpertService extends BaseService
{
    protected string $modelClassName = 'ImFriendsExpertModel';

    /**
     * 用户获取专家好友列表
     *
     * @param $params
     * @param array $search
     * @return array
     */
    public function getFriendsExpertByUser($params, $search = [])
    {
        $where = [
            ['user_id', '=', $search['user_id']],
            ['ue.delete_at', '=', 0]
        ];
        // 复杂查询 DB-#-
        $query = Db::connect('communal')->view(['56002_im_friends_expert' => 'iuaf'], ['user_id', 'expert_id'])
            ->view(['63000_user_expert' => 'ue'], ['customer_id' => 'admin_id', 'name' => 'expert_name', 'avatar' => 'expert_avatar'], 'iuaf.expert_id = ue.id', 'LEFT')
            ->view(['56000_im_message' => 'im'], ['type', 'content' => 'chat_content', 'created_at' => 'chat_created_at'], "im.chat_mark = concat('Admin_', ue.customer_id, '_User_', iuaf.user_id) and im.`id` in (select max(`id`) from `56000_im_message` im2 where im2.state in (1,2) and type = 1 group by im2.chat_mark)", 'LEFT')
            ->where($where)
            ->order('chat_created_at', 'desc');
        if (isset($params['page']) && isset($params['page_size'])) {
            // 分页
            list($page, $page_size) = $this->pageByParams($params);
            $query->page($page, $page_size);
        }
        $list = $query->select()
            ->each(function ($item) use ($search) {
                // 专家头像
                $item['expert_avatar'] = !empty($item['expert_avatar']) ? StringFacade::splicingDomainShowUrl($item['expert_avatar']) : config('domain.api') . '/static/web/images/default_avatar.png';
                // 是否存在未读
                $unreadCount = invoke(ChatService::class)->getNumberByState($item['admin_id'], ImMessageModel::MORPH_TYPE_ONE, $search['user_id'], ImMessageModel::MORPH_TYPE_TWO, ImMessageModel::STATE_ONE);
                $item['chat_state'] = $unreadCount > 0 ? ImMessageModel::STATE_ONE : ImMessageModel::STATE_TWO;
                // chat_content处理
                if (empty($item['chat_content'])) {
                    $item['type'] = '1';
                    $item['chat_content'] = '暂无消息';
                    $item['chat_created_at'] = '';
                } else {
                    $item['chat_created_at'] = Carbon::createFromTimestamp($item['chat_created_at'])->format('Y-m-d H:i');
                }

                return $item;
            });
        $total = Db::connect('communal')->view(['56002_im_friends_expert' => 'iuaf'], ['user_id', 'expert_id'])
            ->view(['63000_user_expert' => 'ue'], ['customer_id' => 'admin_id', 'name' => 'expert_name', 'avatar' => 'expert_avatar'], 'iuaf.expert_id = ue.id', 'LEFT')
            ->view(['56000_im_message' => 'im'], ['type', 'content' => 'chat_content', 'created_at' => 'chat_created_at'], "im.chat_mark = concat('Admin_', ue.customer_id, '_User_', iuaf.user_id) and im.`id` in (select max(`id`) from `56000_im_message` im2 where im2.state in (1,2) group by im2.chat_mark)", 'LEFT')
            ->where($where)
            ->count();

        return [
            'items' => $list,
            'total' => $total,
        ];
    }

    /**
     * 获取列表根据修改时间排序
     *
     * @param $params
     * @param array $search_fields
     * @param array $search
     * @param array $with
     * @param null $eachCall
     * @param bool $isPage
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getListOrderByUpdateAt($params, array $search_fields = [], array $search = [], $with = [], $eachCall = null, $isPage = true)
    {
        list($page, $page_size) = $this->pageByParams($params);
        $order = ['updated_at' => 'desc'];

        $query = ImFriendsExpertModel::field(ImFriendsExpertModel::$column)
            ->with($with)
            ->withSearch($search_fields, $search)
            ->order($order);
        if ($isPage) {
            $query = $query->page($page, $page_size);
        }
        $query = $query->select();
        if (is_callable($eachCall)) {
            $query = $query->each($eachCall);
        }
        $list = $query->toArray();
        $total = ImFriendsExpertModel::withSearch($search_fields, $search)->count();

        return [
            'items' => $list,
            'total' => $total,
        ];
    }
}
